package handingIn;

import beans.SessionManagedBean;
import com.icesoft.faces.context.FileResource;
import groups.ExerciseGroup;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import lecture.Lecture;
import lecture.LectureAdminManagedBean;
import lecture.LectureManagedBean;
import task.ExerciseSheet;
import user.Role;
import user.User;

/**
 *
 * @author Thorsten Ludwig
 */

@ManagedBean(name="downloadHandingInBean")
@ViewScoped
public class DownloadHandingInManagedBean {
    
    
    
    
    public FileResource getDownloadZip(ExerciseSheet sheet) throws FileNotFoundException, IOException {        
        FacesContext context = FacesContext.getCurrentInstance();        
        SessionManagedBean sb = context.getApplication().evaluateExpressionGet(context, "#{sessionBean}", SessionManagedBean.class);
        LectureAdminManagedBean lectureAdmin = context.getApplication().evaluateExpressionGet(context, "#{lectureAdminBean}", LectureAdminManagedBean.class);
        LectureManagedBean lb = sb.getLectureBean();
        Lecture lecture = lb.getLecture();
        User user = sb.getUser();
        Role role = user.getUserRole(lecture.getInfo().getName());
        if (role == Role.TUTOR) {
            List<ExerciseGroup> groups = lectureAdmin.getUserExerciseGroupsWhereLeader(user);
            List<String> students = filterStudents(groups, lecture);
            
            return this.createZipArchive(students, sheet, lecture);
        } else {
            return this.createZipArchive(this.userListToStringList(lecture.getStudents()), sheet, lecture);
        }
        
    }
    
    private byte[] getBuffer(String fileName) {
        BufferedInputStream bis = null;
        byte[] buffer = null;
        try
        {
           bis = new BufferedInputStream( new FileInputStream(fileName) );
           int avail = bis.available();
           buffer = new byte[avail] ;
           if ( avail>0 )
           {
              bis.read(buffer, 0, avail) ;
           }
        }
        catch(IOException ex)
        {
        }
        finally
        {
           try
           {
              if(bis!=null) bis.close();
           }
           catch(Exception ex)
           {
           }
        }
        return buffer;
    }
    
    
    public FileResource createZipArchive(List<String> users, ExerciseSheet sheet, Lecture lecture) throws FileNotFoundException, IOException {
        //TODO: zufälliger Name, solution in der OutputResource
        String outFilename = "solution.zip";
        Map<String, Map<HandingIn, File>> map = lecture.getHandingIns().get(sheet).getField();
        ZipOutputStream zipOut = new ZipOutputStream (new FileOutputStream(outFilename));
        for (String user: users) {
            Map<HandingIn, File> hiMap = map.get(user);
            for (HandingIn hi: sheet.getHandingIns()) {
                File file = hiMap.get(hi);
                if (file != null) {
                    ZipEntry ze = new ZipEntry(user + "/" + hi.getPreFixFile() + hi.getName());
                    zipOut.putNextEntry(ze);
                    byte[] buffer = this.getBuffer(file.getAbsolutePath());
                    zipOut.write(buffer);
                    zipOut.closeEntry();                    
                }
            }
        }
        zipOut.close();
        return new FileResource(new File(outFilename));
    }
    
    private List<String> userListToStringList(List<User> user) {
        List<String> list = new ArrayList<String>();
        for (User u: user){
            list.add(u.getUsername());
        }
        return list;
    }

    private List<String> filterStudents(List<ExerciseGroup> groups, Lecture lecture) {
        List<String> students = new ArrayList<String>();
        for (ExerciseGroup eg: groups) {
            if (eg.getLecture().equals(lecture)) {
                students.addAll(eg.getStudents());
            }
        }
        return students;
    }
    
}
